////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxchisession.h
/// @brief Declarations for CHISession class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CAMXCHISESSION_H
#define CAMXCHISESSION_H

#include "camxchitypes.h"
#include "camxdefs.h"
#include "camxpipeline.h"
#include "camxsession.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Forward Declaration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CHIDevice;

/// @brief Data required for creating a CHI session
/// @todo (CAMX-2491) Delete this and just keep SessionCreateData
struct CHISessionCreateData
{
    SessionCreateData sessionCreateData;            ///< Session (API agnostic) create data
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief  CHISession contains information specific to the CHI API
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CHISession : public Session
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Creates an instance of the object of this class
    ///
    /// @param  pCreateData Data for creating the instance
    ///
    /// @return CHISession*
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CHISession* Create(
        CHISessionCreateData* pCreateData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Destroy
    ///
    /// @brief  Destroys object of this class
    ///
    /// @param  isForced if normal or forced
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    VOID Destroy(
        BOOL isForced);

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DispatchResults
    ///
    /// @brief  Dispatch a set of HAL3 results to the Android framework
    ///
    /// @param  pCaptureResults      The set of results to be dispatched
    /// @param  numCaptureResults    The number of results in the set
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult DispatchResults(
        ChiCaptureResult*   pCaptureResults,
        UINT32              numCaptureResults);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DispatchNotify
    ///
    /// @brief  Dispatch a HAL3 notify message to the Android framework
    ///
    /// @param  pNotifyMessage The message to notify
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult DispatchNotify(
        ChiMessageDescriptor* pNotifyMessage);

private:

    CHISession(const CHISession&) = delete;                                       ///< Disallow the copy constructor
    CHISession& operator=(const CHISession&) = delete;                            ///< Disallow assignment operator

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Module
    ///
    /// @brief  Module constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CHISession() = default;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~CHISession
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~CHISession();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ThreadJobCallback
    ///
    /// @brief  ThreadJobCallback function invoked by the worker thread in the ThreadManager
    ///
    /// @param  pData Thread payload
    ///
    /// @return NULL
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static VOID* ThreadJobCallback(
        VOID* pData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ThreadJobExecute
    ///
    /// @brief  ThreadJobExecute function to process requests and results
    ///
    /// @return CamxResultSuccess, failure otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult ThreadJobExecute();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UnregisterThreadJobCallback
    ///
    /// @brief  Unregister thread job family
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID UnregisterThreadJobCallback();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Initialize
    ///
    /// @brief  Initialize the class after creation
    ///
    /// @param  pCreateData Create data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult Initialize(
        CHISessionCreateData* pCreateData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// InitializeOutResults
    ///
    /// @brief  Initialize the results structure prior to be sending out the results
    ///
    /// @param  pCaptureResults Original capture results structure
    /// @param  pOutResults     Out results structure
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID InitializeOutResults(
        const Camera3CaptureResult* pCaptureResults,
        Camera3CaptureResult*       pOutResults);

    static volatile UINT s_numInstances;        ///< Number of instances
    UINT                 m_localInstance;       ///< Local instance number
};

CAMX_NAMESPACE_END

#endif // CAMXCHISESSION_H
